<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:x="https://www.texmacs.org/2002/extensions" xmlns:m="http://www.w3.org/1998/Math/MathML">
  <head>
    <title>TeXmacs notes</title>
    <meta content="TeXmacs 1.99.15" name="generator"></meta>
    <link href="../resources/notes-base.css" type="text/css" rel="stylesheet"></link>
    <link href="../resources/blog-icon.png" rel="icon"></link>
    <script src="../resources/highlight.pack.js" language="javascript" defer></script>
    <script src="../resources/notes-base.js" language="javascript" defer></script>
  </head>
  <body>
    <div class="toggle" style="display: none">
      <p>
        
      </p>
    </div>
    <div class="notes-header">
      <p>
        <img class="image" src="../resources/texmacs-blog-transparent.png" width="28.116784"></img><span style="margin-left: 2pt"></span><a href="./main.html">[main]</a><em
        class="notes-header-name">Notes on TeXmacs</em>
      </p>
    </div>
    <h1 id="auto-1">Adding a dialog to build websites<span style="margin-left: 1em"></span></h1>
    <div class="notes-abstract">
      In this article we document the construction of a user interface to the
      website building facilities of TeXmacs.
    </div>
    <h2 id="auto-2">Generating websites<span style="margin-left: 1em"></span></h2>
    <p>
      TeXmacs can be used to build websites, in fact <a href="https://texmacs.github.io/notes">this</a> blog,
      the main <a href="www.texmacs.org">TeXmacs website</a> and a couple of other websites
      (e.g. one <a href="https://www.texmacs.org/joris/main/joris.html">here</a> and another one <a href="http://www.mathemagix.org/www/mmdoc/doc/html/main/index.en.html">here</a>) are
      currently written and maintained exclusively within TeXmacs. 
    </p>
    <p>
      To avoid the need of exporting manually every single page to HTML, some
      support has been added to build websites in the form of Scheme
      procedures, to be found in the module <tt class="verbatim scheme">(doc tmweb)</tt> (which
      can be found at <tt class="verbatim">TeXmacs/progs/doc/tmweb.scm</tt>). The two
      relevant exported procedures are <tt class="verbatim scheme">tmweb-update-dir</tt> and
      <tt class="verbatim scheme">tmweb-convert-dir</tt>. 
    </p>
    <p>
      For example the user can invoke TeXmacs for the command line with
      something like
    </p>
    <div class="tmweb-code">
      <pre class="verbatim" xml:space="preserve">
texmacs -x &quot;(tmweb-convert-dir \&quot;sourcedir\&quot; \&quot;target-dir\&quot;)&quot; -q</pre>
    </div>
    <p>
      which executes (option <tt class="verbatim">-x</tt>) the Scheme command 
    </p>
    <div class="tmweb-code">
      <pre class="verbatim scheme" xml:space="preserve">
(tmweb-convert-dir &quot;sourcedir&quot; &quot;target-dir&quot;)</pre>
    </div>
    <p>
      and then exits (option <tt class="verbatim">-q</tt>). Here <var>source-dir</var>
      and <var>target-dir</var> are two filesystem paths to the source and
      target directories for the conversion. The procedure <tt class="verbatim scheme">tmweb-convert-dir</tt>
      will take every <tt class="verbatim">.tm</tt> file in <var>source-dir</var>,
      convert it to its HTML counterpart  and save it in
      <var>target-dir</var>, all the other file types are just copied (see the
      sources for more details). <tt class="verbatim scheme">tmweb-update-dir</tt> will convert
      only files which are newer than their counterpart in
      <var>target-dir</var>, if it exists. This is suitable for incremental
      updating a website which has been already generated at least once with
      <tt class="verbatim scheme">tmweb-convert-dir</tt>.
    </p>
    <p>
      TeXmacs (here we refer to version 1.99.15 but this functionality existed
      already for some time) disposes of menu items to initiate both
      operations (creation and update). They can be found in <class class="tmweb-menu"
      style="font-family: sans-serif">Tools</class>&rarr;<class class="tmweb-menu" style="font-family: sans-serif">Web</class>&rarr;<class
      class="tmweb-menu" style="font-family: sans-serif">Create web site<span style="margin-left: 0.16665em"></span>.<span style="margin-left: 0.16665em"></span>.<span
      style="margin-left: 0.16665em"></span>.<span style="margin-left: 0.16665em"></span></class><a id="auto-3"></a> and <class class="tmweb-menu"
      style="font-family: sans-serif">Tools</class>&rarr;<class class="tmweb-menu" style="font-family: sans-serif">Web</class>&rarr;<class
      class="tmweb-menu" style="font-family: sans-serif">Update web site<span style="margin-left: 0.16665em"></span>.<span style="margin-left: 0.16665em"></span>.<span
      style="margin-left: 0.16665em"></span>.<span style="margin-left: 0.16665em"></span></class><a id="auto-4"></a>. The dots (<span
      style="margin-left: 0.16665em"></span>.<span style="margin-left: 0.16665em"></span>.<span style="margin-left: 0.16665em"></span>.<span style="margin-left: 0.16665em"></span>)
      indicate that both items will execute some operation only after an
      interaction with the user (this is standard for all menu items, see e.g.
      <class class="tmweb-menu" style="font-family: sans-serif">File</class>&rarr;<class class="tmweb-menu" style="font-family: sans-serif">Save as<span
      style="margin-left: 0.16665em"></span>.<span style="margin-left: 0.16665em"></span>.<span style="margin-left: 0.16665em"></span>.<span style="margin-left: 0.16665em"></span></class><a
      id="auto-5"></a>). In particular in this case these items calls the scheme
      procedures <tt class="verbatim scheme">tmweb-interactive-build</tt> or <tt class="verbatim scheme">tmweb-interactive-update</tt>.
      The first, for example, looks like
    </p>
    <div class="tmweb-code">
      <pre class="verbatim scheme" xml:space="preserve">
(tm-define (tmweb-interactive-build)
  (:interactive #t)
  (user-url &quot;Source directory&quot; &quot;directory&quot; 
    (lambda (src)  (user-url &quot;Destination directory&quot; &quot;directory&quot;
      (lambda (dest) (tmweb-convert-directory src dest #f #f))))))</pre>
    </div>
    <p>
      The declaration <tt class="verbatim scheme">(:interactive #t)</tt> indicates to TeXmacs
      that this procedur will prompt the user for some information. In
      particular, the dots in the menu item are added automatically by TeXmacs
      to reflect this declaration. The meaning of the actual code is quite
      intuitive: the procedure <tt class="verbatim scheme">user-url</tt> prompt the user for
      some information, the UI is supposed to show somehow the string <tt
      class="verbatim scheme">&quot;Source directory&quot;</tt> to give an hint to the user
      about the content of the information required. The argument <tt class="verbatim scheme">&quot;directory&quot;</tt>
      indicates that valid results should be an  URL pointing to a directory
      in the filesystem. Finally the third argument to <tt class="verbatim scheme">user-url</tt>
      is a Scheme closure accepting one argument. When this procedure is
      evaluated, it initiate a UI dialog with the user which can select a
      directory and then press &ldquo;Ok&rdquo; to confirm the selection. At
      this point the closure is called with an argument given by a string
      representing the URL just chosen. In the case above this result appears
      in the variable <tt class="verbatim scheme">src</tt>. Subsequently the closure evaluate
      an additional <tt class="verbatim scheme">user-url</tt> invocation, which asks for a
      destination directory an provide a second closure which looks like
    </p>
    <div class="tmweb-code">
      <pre class="verbatim scheme" xml:space="preserve">
(lambda (dest) (tmweb-convert-directory src dest #f #f))</pre>
    </div>
    <p>
      This closure receives the destination directory in the variable <tt
      class="verbatim scheme">dest</tt> and has also access to the variable <tt class="verbatim scheme">src</tt>
      because this last variable is visible (thanks to the lexical scoping of
      Scheme) to all the expressions inside the first <tt class="verbatim scheme">lambda</tt>.
      As a result the procedure <tt class="verbatim scheme">tmweb-convert-directory</tt> will
      be invocated with the user provided values for <tt class="verbatim scheme">src</tt> and
      <tt class="verbatim scheme">dest</tt> and two additional boolean arguments (the first
      indicates whether we need to update or not and we will ignore the second
      here).
    </p>
    <p>
      Albeit <tt class="verbatim scheme">tmweb-interactive-build</tt> is easy to understand and
      write, it is not very convenient, since it does not remember the user's
      choices from previous interactions and oblige the user to repetitive
      actions, for example when developing some new feature of the site which
      requires frequent updating. 
    </p>
    <p>
      <a id="auto-6"></a>
    </p>
    <h2>A new interface<span style="margin-left: 1em"></span></h2>
    <p>
      The goal of this article is to use  TeXmacs Scheme widgets to develop a
      new dialog which allow a nicer interaction with the user. 
    </p>
    <p>
      In particular we want to remember previous choices and give a more
      comprehensive perspective of the parameters in a single window, instead
      of proposint to the users a sequence of questions without any trace of
      the current state of the interaction. The following picture shows the
      design we aim for for this dialog:
    </p>
    <div style="margin-top: 1em; margin-bottom: 1em">
      <table style="width: 100%">
        <tbody><tr>
          <td style="text-align: center; padding-left: 0em; padding-right: 0em"><img class="image" src="../resources/website-builder-dialog/website-builder-dialog-image-1.png" width="100%"></img></td>
        </tr><tr>
          <td style="text-align: center; padding-left: 0em; padding-right: 0em; height: 0.5em"></td>
        </tr><tr>
          <td style="text-align: center; padding-left: 0em; padding-right: 0em; padding-left: 1.5em; padding-right: 1.5em"><div class="caption">
            <font style="font-size: 90.0%"><p>
              <b>Figure 1. </b><a id="auto-7"></a><a id="fig:dialog"></a>The new dialog widget
            </p></font>
          </div></td>
        </tr></tbody>
      </table>
    </div>
    <p>
      This dialog will have to be initiated by a procedure (with no
      parameters) which we will call <tt class="verbatim scheme">website-interactive-builder</tt>.
      Later on we can associate this function to some menu item to give easy
      access to the user to it. We have to manage three values: the source
      directory, the target directory and a boolean value to indicate creation
      or update. The function must read  these values from a store (persistent
      through executions of the program), set up the dialog with these values,
      run the interaction, retrive the values after it and proceed with the
      suitable actions according to the new values. In particular, if the user
      didn't canceled the operation, we need to store away the new values for
      future invocations. This persistency of the information can be obtained
      by leveraging TeXmacs preference system, in particular we have two
      procedures <tt class="verbatim scheme">get-preference</tt> and <tt class="verbatim scheme">set-preference</tt>
      at our disposal. Their use is very simple: we can associate strings to
      given labels (also strings), the associations will persist across
      executions. If a label do not have any associated values so far <tt
      class="verbatim scheme">get-preference</tt> will return the string <tt class="verbatim scheme">&quot;default&quot;</tt>.
      A possible form of <tt class="verbatim scheme">website-interactive-builder</tt> is then
      the following:
    </p>
    <div class="tmweb-code">
      <pre class="verbatim scheme" xml:space="preserve">
(tm-define (website-interactive-builder)
    (let ((src (get-preference &quot;website:src-dir&quot;))
          (dest (get-preference &quot;website:dest-dir&quot;))
          (update? (get-boolean-preference &quot;website:update-flag&quot;)))
      
    (dialogue-window (website-widget src dest update?)
       (lambda (flag src dest update?) 
           (if flag (begin 
              (set-preference &quot;website:src-dir&quot; src)
              (set-preference &quot;website:dest-dir&quot; dest)
              (set-boolean-preference &quot;website:update-flag&quot; update?)
              (if update? 
                    (tmweb-update-dir src dest)
                    (tmweb-convert-dir src dest)))))
        &quot;Website tool&quot;)))</pre>
    </div>
    <p>
      We choose labels <tt class="verbatim scheme">&quot;website:src-dir&quot;</tt>, <tt class="verbatim scheme">&quot;website:dest-dir&quot;</tt>,
      <tt class="verbatim scheme">&quot;website:update-flag&quot;</tt> for the three
      parameters. The <tt class="verbatim scheme">let</tt> initialises local variable with the
      previous values of the parameters and then we invoke <tt class="verbatim scheme">(dialogue-window
      widget func)</tt>. This procedure takes two arguments <tt class="verbatim scheme">widget</tt>
      and <tt class="verbatim scheme">func</tt>: the first is a <i>widget</i> constructed via
      <tt class="verbatim scheme">tm-widget</tt> and the second is a closure which will be
      passed to the widget.  The actual widget is constructed in the
      invocation to <tt class="verbatim scheme">(website-widget src dest update?)</tt> which
      returns the executable code which will eventually display the dialog in
      Fig. <a href="#fig:dialog">1</a>. 
    </p>
    <p>
      This is achieved thanks to a custom description language accessed via
      the <tt class="verbatim scheme">tm-widget</tt> macro.
    </p>
    <h2 id="auto-8">Describing widgets in Scheme<span style="margin-left: 1em"></span></h2>
    <p>
      The macro <tt class="verbatim scheme">tm-widget</tt> allows to use Scheme forms to
      construct a wide variety of UI elements from a set of basic
      <i>primitive</i> elements. For detailed information please refert to
      <class class="tmweb-menu" style="font-family: sans-serif">Help</class>&rarr;<class class="tmweb-menu" style="font-family: sans-serif">Scheme
      extensions</class>&rarr;<class class="tmweb-menu" style="font-family: sans-serif">Customizing and exending
      the user interface</class><a id="auto-9"></a>. Our goal here is to provide an
      example of how the technique described in the help pages apply to our
      present problem.
    </p>
    <p>
      Let us give right away a possibile definition for <tt class="verbatim scheme">(website-widget
      src dest update?)</tt>:
    </p>
    <div class="tmweb-code">
      <pre class="verbatim scheme" xml:space="preserve">

(tm-widget ((website-widget src-dir dest-dir update?)  cmd)
 (padded
  (vertical
   (hlist &gt;&gt;&gt; (text &quot;Website creation tool&quot;) &gt;&gt;&gt;)
   ===
   (refreshable &quot;website-tool-dialog-source&quot;  (hlist 
     (text &quot;Source dir      :&quot;) // //
       (hlist
         (input (when answer (set! src-dir answer))
                &quot;file&quot; (list src-dir) &quot;40em&quot;)
         // //
         (explicit-buttons 
            (&quot;choose&quot; 
              (cpp-choose-file 
                 (lambda (u) 
                    (set! src-dir (url-&gt;string u))
                    (refresh-now &quot;website-tool-dialog-source&quot;)) 
                 &quot;Choose source dir&quot; &quot;directory&quot; &quot;&quot; 
                 (string-&gt;url src-dir)))))))
    ===
    (refreshable &quot;website-tool-dialog-dest&quot;  
      (hlist 
        (text &quot;Destination dir:&quot;) // //
        (hlist
          (input (when answer (set! dest-dir answer))
                 &quot;file&quot; (list dest-dir) &quot;40em&quot;)
          // //
          (explicit-buttons 
            (&quot;choose&quot; 
               (cpp-choose-file 
                  (lambda (u) 
                     (set! dest-dir (url-&gt;string u))
                     (refresh-now &quot;website-tool-dialog-dest&quot;)) 
               &quot;Choose dest dir&quot; &quot;directory&quot; &quot;&quot; 
               (string-&gt;url dest-dir)))))))
    ===
    (hlist
      (text &quot;Update:&quot;) //
      (toggle (begin (set! update? answer) 
                     (refresh-now &quot;website-tool-dialog-buttons&quot;))
              update?))
    ===
    (refreshable &quot;website-tool-dialog-buttons&quot;  
       (bottom-buttons &gt;&gt;&gt;
          (&quot;Cancel&quot; (cmd #f src-dir dest-dir update?)) // //
          (if update? 
              (&quot;Update&quot; (cmd #t src-dir dest-dir update?))) 
          (if (not update?) 
              (&quot;Create&quot; (cmd #t src-dir dest-dir update?))))))))
</pre>
    </div>
    <p>
      
    </p>
    <p>
      Note that all this should not be understood as <i>standard</i> Scheme
      code: the evaluation rules of Scheme are superseded by the macro <tt
      class="verbatim scheme">tm-widget</tt> which will receive in input the description above
      and will use it to <i>compile</i> this description of a widget to a
      sequence of invocation of Scheme procedures. In this way we can provide
      a high-level description of widgets without need to code them in Scheme
      with all the gory details. <tt class="verbatim scheme">tm-widget</tt> will take care of
      this for us. 
    </p>
    <p>
      Let us describe the meaning of some of markup tags used above
    </p>
    <ul>
      <li>
        <p>
          <tt class="verbatim scheme">(padded &hellip;)</tt> describes a widget which contains
          other UI elements and pad them with some space around;
        </p>
      </li>
      <li>
        <p>
          <tt class="verbatim scheme">(vertical &hellip;)</tt> compose its arguments in a
          vertical list of UI elements;
        </p>
      </li>
      <li>
        <p>
          <tt class="verbatim scheme">(hlist &hellip;)</tt> do the same but horizontally;
        </p>
      </li>
      <li>
        <p>
          <tt class="verbatim scheme">&gt;&gt;&gt;</tt>, <tt class="verbatim scheme">===</tt>, <tt class="verbatim scheme">//</tt>
          are primitive elements (i.e. their definition is complete without
          referring to other content) which indicate various kind of spacing
          among the sorrounding elements;
        </p>
      </li>
      <li>
        <p>
          <tt class="verbatim scheme">(text &quot;a string&quot;)</tt> define a UI element
          which show the given string;
        </p>
      </li>
      <li>
        <p>
          <tt class="verbatim scheme">(refreshable &quot;label&quot; w)</tt> indicates that the
          widget <tt class="verbatim scheme">w</tt> must be refreshed when the procedure <tt
          class="verbatim scheme">(refresh-now &quot;label&quot;)</tt> is evaluated. It allow
          widgets to dynamically change in response to some action happening
          elsewhere in the code.
        </p>
      </li>
      <li>
        <p>
          <tt class="verbatim scheme">(input code &quot;file&quot; (list choice1 choice2
          &hellip;) &quot;40em&quot;)</tt> represents an text input UI element
          which accepts file names and which will have a horizontal size of
          40em. The <tt class="verbatim scheme">code</tt> form will be evaluated every time the
          text field change, within that form the symbol <tt class="verbatim scheme">answer</tt>
          refers to the value of the text field, if <tt class="verbatim scheme">answer</tt> is
          <tt class="verbatim scheme">#f</tt> then the evaluation is not a result of an
          interaction with the user, so one has to check for this (It is not
          clear to me the reasons of this design, but it happens to be so, a
          deeper analysis of <tt class="verbatim scheme">tm-widget</tt> inner design would be
          needed to get a grasp on this).
        </p>
      </li>
      <li>
        <p>
          <tt class="verbatim scheme">(explicit-buttons (&quot;label1&quot; form1)
          (&quot;label2&quot; form2) &hellip;)</tt> describe a row of buttons
          with various labels. When they are pushed the respective forms are
          evaluated. For example, in the code above, the first button calls
          the function <tt class="verbatim scheme">cpp-choose-file</tt> with parameters as
          follows:
        </p>
        <div class="tmweb-code">
          <pre class="verbatim scheme" xml:space="preserve">
(cpp-choose-file 
    (lambda (u) (set! src-dir (url-&gt;string (url-&gt;string u))                    (refresh-now &quot;website-tool-dialog-source&quot;)) 
    &quot;Choose source dir&quot; &quot;directory&quot; &quot;&quot; 
    (string-&gt;url src-dir))))</pre>
        </div>
        <p>
          This function (implemented in C++) opens the GUI file chooser dialog
          and initiate the modal interaction with the user to ask her a path
          of kind <tt class="verbatim scheme">&quot;directory&quot;</tt>. The default directory
          is given by <tt class="verbatim scheme">(string-&gt;url src-dir)</tt>. When the user
          terminates the dialog pressing the &ldquo;Open&rdquo; button, then
          the chosen URL is passed to the closure in the variable <tt class="verbatim scheme">u</tt>,
          we store this value in the <tt class="verbatim scheme">src-dir</tt> variable (which
          is visible in all the syntactic context of <tt class="verbatim scheme">(website-widget
          src-dir dest-dir update?)</tt>, i.e. in the whole definition of the
          widget, and then we invoke <tt class="verbatim scheme">(refresh-now
          &quot;website-tool-dialog-source&quot;)</tt> to update the
          corresponding <tt class="verbatim scheme">refreshable</tt> widget, i.e. update the
          text field with the appropriate value.
        </p>
      </li>
      <li>
        <p>
          <tt class="verbatim scheme">(toogle form value)</tt> describes a UI checkbox which
          takes its value from the <tt class="verbatim scheme">value</tt> and which when
          switched (i.e. toggle its state) evaluates the form <tt class="verbatim scheme">form</tt>
          with the symbol <tt class="verbatim scheme">answer</tt> evaluating to the current
          state of the checkbox.
        </p>
      </li>
      <li>
        <p>
          <tt class="verbatim scheme">(bottom-buttons &hellip;)</tt> describe the buttons which
          should be located in the bottom right corner of the dialog.
          Typically these are the &ldquo;Cancel&rdquo; and &ldquo;Ok&rdquo;
          buttons. In our case we want to show a different label whether we
          are going to &ldquo;Create&rdquo; the site or only
          &ldquo;Update&rdquo; it.
        </p>
      </li>
    </ul>
    <p>
      Note the use of the parameter <tt class="verbatim scheme">cmd</tt> which will be passed
      to <tt class="verbatim scheme">(website-widget src-dir dest-dir update?)</tt> by <tt
      class="verbatim scheme">dialogue-window</tt>. That is, <tt class="verbatim scheme">(dialogue-window a
      b)</tt> expects as its argument <tt class="verbatim scheme">a</tt> a closure with one
      argument (i.e. <tt class="verbatim scheme">(lambda (cmd) &hellip;)</tt>) and <tt class="verbatim scheme">b</tt>
      another closure (with arbitrary many arguments) and upon execution, it
      call the closure <tt class="verbatim scheme">a</tt> with <tt class="verbatim scheme">b</tt> as argument.
      Therefore in the widget we have that <tt class="verbatim scheme">cmd</tt> points to the
      closure <tt class="verbatim scheme">b</tt>. In our case calling <tt class="verbatim scheme">(cmd #t
      src-dir dest-dir update?)</tt> inside the widget will result in the
      evaluation of the closure
    </p>
    <div class="tmweb-code">
      <pre class="verbatim scheme" xml:space="preserve">
(lambda (flag src dest update?) 
           (if flag (begin 
              (set-preference &quot;website:src-dir&quot; src)
              (set-preference &quot;website:dest-dir&quot; dest)
              (set-boolean-preference &quot;website:update-flag&quot; update?)
              (if update? 
                    (tmweb-update-dir src dest)
                    (tmweb-convert-dir src dest)))))</pre>
    </div>
    <p>
      with <tt class="verbatim scheme">flag</tt> set to <tt class="verbatim scheme">#t</tt> and with the other
      three argument set to the appropriate values. We can then finalize the
      interaction by storing away the values into the program's preferences
      and either call <tt class="verbatim scheme">tmweb-update-dir</tt> or <tt class="verbatim scheme">tmweb-convert-dir</tt>.
    </p>
    <p>
      
    </p>
  </body>
</html>